from datetime import datetime
from typing import Generic, List, Optional, Type, TypeVar

from fastapi import Query
from pydantic import BaseModel, Field
# from pydantic.generics import GenericModel
from tortoise.queryset import QuerySet


# class ResponseModel(GenericModel):
class ResponseModel(BaseModel):
    """ 可以使用别名的响应模型 """

    class Config:
        # 
        # allow_population_by_field_name = True
        population_by_field_name = True


Model = TypeVar('Model', bound='BaseModel') # 泛类型注解


class ORMModel(BaseModel):
    """ 带orm的pydantic模型 """

    class Config:
        # 允许模型与 ORM 模型兼容，通过允许使用非字典对象进行模型初始化。
        # orm_mode = True
        from_attributes=True
        # 允许通过字段名称而不是别名来填充模型数据。
        # allow_population_by_field_name = True
        population_by_field_name = True

    @classmethod
    async def from_queryset(cls: Type['Model'], qs: QuerySet) -> List["Model"]:
        # return [cls.from_orm(x) for x in await qs]
        return [cls.model_validate(x) for x in await qs]


DataT = TypeVar("DataT")  # 泛型类型 响应的数据


class FailResp(ResponseModel, Generic[DataT]):
    """ 失败的响应 """
    code: int = Field(..., gt=0, description='状态码')
    msg: str = Field(..., description='信息摘要', serialization_alias='message')
    data: Optional[DataT] = Field(None, description='响应的数据', serialization_alias='result')


class SuccessResp(ResponseModel, Generic[DataT]):
    """ 成功的响应 """
    code: int = Field(0, description='状态码')
    # alias 使用,前后端都需用这个别名
    # serialization_alias  序列化时使用的别名,给前端使用  后端不用管,依然使用字段名
    msg: str = Field('success', description='信息摘要', alias='message')
    data: Optional[DataT] = Field(None, description='响应的数据', serialization_alias='result')


class SingleResp(SuccessResp, Generic[DataT]):
    """ 响应单个对象 """
    data: DataT = Field(..., description='响应的数据', serialization_alias='result')


class MultiResp(SuccessResp, Generic[DataT]):
    """ 响应多个对象 """
    data: List[DataT] = Field(..., description='响应的数据', serialization_alias='result')


# class PageData(GenericModel, Generic[DataT]):
class PageData(BaseModel, Generic[DataT]):
    """ 分页响应的数据部分 """
    total: int = Field(..., description='总数量')
    items: List[DataT]


class PageResp(SuccessResp, Generic[DataT]):
    """ 分页响应 vben """
    data: PageData[DataT] = Field(..., description='响应的数据', serialization_alias='result')


class BaseFilter(ORMModel):
    """ 过滤的基础字段 """
    status: Optional[bool] = Query(None, description="状态")
    create_time__gte: Optional[datetime] = Query(None, alias="createTimeStart", description="创建时间-起点")
    create_time__lte: Optional[datetime] = Query(None, alias="createTimeEnd", description="创建时间-终点")
